---
title: Code Mentions
description: Highlight code when hovering over text
layout: PreviewAndImplementation
---

## !demo

Add a language picker when you need to switch between languages in a code block.

<Demo name="hover" content="content.mdx">
  Hover the mentions
</Demo>

## !implementation

```tsx code.tsx -c
import {
  AnnotationHandler,
  InnerLine,
  Pre,
  RawCode,
  highlight,
} from "codehike/code"
import React from "react"
import Content from "./content.mdx"
import "./styles.css"

export default function Page() {
  return <Content components={{ HoverContainer, a: Link, Code }} />
}

function HoverContainer(props: { children: React.ReactNode }) {
  return <div className="hover-container">{props.children}</div>
}

// !fold[/className="(.*?)"/gm]
function Link(props: { href?: string; children?: React.ReactNode }) {
  if (props.href?.startsWith("hover:")) {
    const hover = props.href.slice("hover:".length)
    return (
      <span
        className="underline decoration-dotted underline-offset-4"
        data-hover={hover}
      >
        {props.children}
      </span>
    )
  } else {
    return <a {...props} />
  }
}

async function Code({ codeblock }: { codeblock: RawCode }) {
  const highlighted = await highlight(codeblock, "github-dark")
  return <Pre code={highlighted} handlers={[hover]} />
}

const hover: AnnotationHandler = {
  name: "hover",
  onlyIfAnnotated: true,
  Line: ({ annotation, ...props }) => (
    <InnerLine
      merge={props}
      className="transition-opacity"
      data-line={annotation?.query || ""}
    />
  ),
}
```

We also need to add some CSS **for each value of the `data-hover` attribute**.

```css styles.css
.hover-container:has([data-hover="one"]:hover)
  [data-line]:not([data-line="one"]),
.hover-container:has([data-hover="two"]:hover)
  [data-line]:not([data-line="two"]) {
  opacity: 0.5;
}
```

You can change the CSS to fit your needs.

If you need a more complex behavior, you could add a React Context Provider to the `HoverContainer` component and use it to store the current hover state. Then, you can use the `useContext` hook in the `Line` component to check if the current line is the one being hovered over.
